﻿using Cofe.Core.Validater;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq.Expressions;
using Cofe.Core.Implements;

namespace Cofe.Core.Property
{
    public interface IPropertyDictionary : ICofeService
    {
        /// <summary>
        /// When set, dictionary extract a list of properties from Definitions.
        /// </summary>
        IPropertyDefinitions[] PropertyDefinitions { get; set; }

        /// <summary>
        /// Return all properties registered.
        /// </summary>
        IEnumerable<object> Properties { get; }

        /// <summary>
        /// Lookup a property from it's property string.
        /// </summary>
        /// <param name="propertyString"></param>
        /// <returns></returns>
        object GetProperty(string propertyString);

        /// <summary>
        /// Lookup a property from it's property id.
        /// </summary>
        /// <param name="propertyString"></param>
        /// <returns></returns>
        object GetProperty(int propId);

        /// <summary>
        /// Use a property string to find a property.
        /// </summary>
        /// <param name="property"></param>
        /// <returns></returns>
        string GetPropertyString(object property);

        /// <summary>
        /// Return a list of property with default value.
        /// </summary>
        /// <returns></returns>
        List<object> GetPropertiesWithDefaultValue();

        IPropertyDefinitions GetPropertyDefinition(object property);

        Expression<Func<CofeSystemInfo, T>> GetPropertyExpression<T>(object property);

        /// <summary>
        /// Return whether a property exists in the dictionary.
        /// </summary>
        /// <param name="property"></param>
        /// <returns></returns>
        bool HasProperty(object property);

        bool HasProperty(string propertyString);

        /// <summary>
        /// Take a set of properties and create property definitions based on the registered PropertyDefinitions.
        /// </summary>
        /// <param name="properties"></param>
        /// <param name="propertyDefinitionsSet">Use PropertyDictionary's PropertyDefinitions if not specified.</param>
        /// <returns></returns>
        IPropertyDefinitions[] CreatePropertyDefinitions(IEnumerable<object> properties, 
            params IPropertyDefinitions[] propertyDefinitionsSet);

        IPropertyAttributeHelper AttributeHelper { get; set; }
        IPropertyInvoker PropertyInvoker { get; set; }
    }
}
